<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Prop</title>
    <script type="text/javascript" src="../js/vue.js"></script>
</head>

<body>
    <!-- 在 HTML 中是 kebab-case 的 -->
    <div id="blog-post-demo1">
        <blog-post post-title="hello!"></blog-post>
    </div>

    <!-- 传递静态Prop -->
    <div id="blog-post-demo2">
        <!-- 动态赋予一个变量的值 -->
        <blog-post2 title="My journey with Vue"></blog-post2>

        <!-- 动态赋予一个复杂表达式的值 -->
        <!-- <blog-post v-bind:title="post.title + ' by ' + post.author.name"></blog-post> -->
    </div>

    <!-- 传入一个数字 -->
    <div id="blog-post-demo3">
        <!-- 即便 `42` 是静态的，我们仍然需要 `v-bind` 来告诉 Vue -->
        <!-- 这是一个 JavaScript 表达式而不是一个字符串。-->
        <blog-post3 v-bind:likes="42"></blog-post3>
    </div>

    <!-- 传入一个布尔值 -->
    <div>
        <!-- 包含该 prop 没有值的情况在内，都意味着 `true`。-->
        <blog-post is-published></blog-post>

        <!-- 即便 `false` 是静态的，我们仍然需要 `v-bind` 来告诉 Vue -->
        <!-- 这是一个 JavaScript 表达式而不是一个字符串。-->
        <blog-post v-bind:is-published="false"></blog-post>

        <!-- 用一个变量进行动态赋值。-->
        <blog-post v-bind:is-published="post.isPublished"></blog-post>
    </div>

    <!-- 传入一个数组 -->
    <div>
        <!-- 即便数组是静态的，我们仍然需要 `v-bind` 来告诉 Vue -->
        <!-- 这是一个 JavaScript 表达式而不是一个字符串。-->
        <blog-post v-bind:comment-ids="[234, 266, 273]"></blog-post>

        <!-- 用一个变量进行动态赋值。-->
        <blog-post v-bind:comment-ids="post.commentIds"></blog-post>
    </div>

    <!-- 传入一个对象 -->
    <div>
        <!-- 即便对象是静态的，我们仍然需要 `v-bind` 来告诉 Vue -->
        <!-- 这是一个 JavaScript 表达式而不是一个字符串。-->
        <blog-post v-bind:author="{
            name: 'Veronica',
            company: 'Veridian Dynamics'
            }">
        </blog-post>

        <!-- 用一个变量进行动态赋值。-->
        <blog-post v-bind:author="post.author"></blog-post>
    </div>

    <!-- 传入一个对象的所有 property 
    
        post: {
            id: 1,
            title: 'My Journey with Vue'
        }

    -->
    <div>
        <blog-post v-bind="post"></blog-post>
        <!-- 等价于： -->
        <blog-post v-bind:id="post.id" v-bind:title="post.title"></blog-post>
    </div>



</body>
<script>

    // Prop 的大小写 
    Vue.component('blog-post', {
        // 在 JavaScript 中是 camelCase 的
        props: ['postTitle'],
        template: '<h3>{{ postTitle }}</h3>'
    })
    new Vue({
        el: '#blog-post-demo1'
    });

    Vue.component('blog-post2', {
        props: ['title'],
        template: '<h3>{{ title }}</h3>'
    })
    new Vue({
        el: '#blog-post-demo2'
    });

    Vue.component('blog-post3', {
        props: ['likes'],
        template: '<h3>{{ likes }}</h3>'
    })
    new Vue({
        el: '#blog-post-demo3'
    });

    // 单向数据流
    Vue.component('blog-post-init', {
        props: ['initialCounter'],
        data: function () {
            return {
                counter: this.initialCounter
            }
        }
    })

    // Prop 验证
    Vue.component('my-component', {
        props: {
            // 基础的类型检查 (`null` 和 `undefined` 会通过任何类型验证)
            propA: Number,
            // 多个可能的类型
            propB: [String, Number],
            // 必填的字符串
            propC: {
                type: String,
                required: true
            },
            // 带有默认值的数字
            propD: {
                type: Number,
                default: 100
            },
            // 带有默认值的对象
            propE: {
                type: Object,
                // 对象或数组默认值必须从一个工厂函数获取
                default: function () {
                    return { message: 'hello' }
                }
            },
            // 自定义验证函数
            propF: {
                validator: function (value) {
                    // 这个值必须匹配下列字符串中的一个
                    return ['success', 'warning', 'danger'].includes(value)
                }
            }
        }
    })

    // Prop 类型
    Vue.component('blog-post1', {
        // props: ['title', 'likes', 'isPublished', 'commentIds', 'author']
        props: {
            title: String,
            likes: Number,
            isPublished: Boolean,
            commentIds: Array,
            author: Object,
            callback: Function,
            contactsPromise: Promise // or any other constructor
        }
    })


</script>

</html>